﻿using FaissOperation.FaissIndex.Index;
using FaissOperation.FaissIndex.Native;
using FaissOperation.FaissIndexFlat;
using FaissOperation.Interface;
using System;

namespace FaissOperation.FaissIndex
{
    public class FaissHelper
    {
        /// <summary>
        /// 对向量进行 L2 归一化。
        /// </summary>
        public static float[] NormalizeForFaiss(float[] vector)
        {
            float norm = 0;
            for (int i = 0; i < vector.Length; i++)
                norm += vector[i] * vector[i];
            norm = (float)Math.Sqrt(norm);
            if (norm > 0)
            {
                var result = new float[vector.Length];
                for (int i = 0; i < vector.Length; i++)
                    result[i] = vector[i] / norm;
                return result;
            }
            return vector;
        }

        /// <summary>
        /// 将自定义 MetricType 转为 Faiss C API 对应的整数值。
        /// Cosine 使用归一化 + InnerProduct 模拟。
        /// </summary>
        public static FaissMetricType ToFaissMetric(MetricType metric)
        {
            return metric switch
            {
                MetricType.L2 => FaissMetricType.METRIC_L2,           // Faiss MetricType.L2
                MetricType.InnerProduct => FaissMetricType.METRIC_INNER_PRODUCT, // Faiss MetricType.IP
                MetricType.Cosine => FaissMetricType.METRIC_INNER_PRODUCT,       // Cosine 用归一化 + IP 模拟
                _ => FaissMetricType.METRIC_L2
            };
        }

        /// <summary>
        /// 轻量检查 Faiss 库是否部署正确。
        /// </summary>
        public static void AssertFaissDeployment()
        {

            // 在使用前测试
            try
            {
                IntPtr testPtr;
                var result = FaissNative.faiss_IndexFlat_new(out testPtr, 128, FaissMetricType.METRIC_L2);
                Console.WriteLine($"Faiss DLL文件加载测试结果: {result}");
                if (testPtr != IntPtr.Zero)
                    FaissNative.faiss_Index_free(testPtr);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"文件加载失败，通常是未找到Faiss DLL文件导致的。请在葡萄城市场中本插件的介绍页面获取faiss类库的最新版本和部署指南，更新设计器与服务器环境。 {ex.Message}");
            }

        }

    }
}
